package com.yantong.controller;

import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import com.yantong.annotation.Log;
import com.yantong.constant.StringConstans;
import com.yantong.pojo.*;
import com.yantong.service.CentreService;
import com.yantong.constant.BusinessCode;
import com.yantong.exception.BDException;
import com.yantong.result.ResultVo;
import com.yantong.service.ConfigService;
import com.yantong.utils.*;
import com.yantong.pojo.BaseConfig;
import com.yantong.service.MenuService;
import com.yantong.service.UserService;
import com.yantong.utils.MD5Utils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 * @author kanghaixin
 */
@Controller
public class LoginController extends BaseController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private MenuService menuService;
    @Autowired
    private UserService userService;
    @Autowired
    private Producer captchaProducer;
    @Autowired
    private CentreService centreService;
    @Autowired
    private ConfigService configService;
    @Value("${spring.redis.host}")
    String s;

    @Value("${spring.datasource.url}")
    String mysql;


    @GetMapping({"/index"})
    public String index(Model model) {
        List<Tree<Permission>> menus = menuService.listMenuTree(getUserId());
        model.addAttribute("menus", menus);
        model.addAttribute("nickname", getUser().getNickname());
        BaseConfig baseConfig = configService.getBaseConfig();
        model.addAttribute("picUrl", baseConfig.getBackMainCloseLogoUrl());
        model.addAttribute("picUrl2", baseConfig.getBackMainOpenLogoUrl());
        BaseConfig centerBaseConfig = configService.getBaseConfig(getUserCentreId());
        //不存在的情况下取平台的
        model.addAttribute("indexBgImg", ValidateUtil.isNotEmptyString(centerBaseConfig.getIndexBgImg()) ? centerBaseConfig.getIndexBgImg() : baseConfig.getIndexBgImg());
        model.addAttribute("leftMenuBgColor", ValidateUtil.isNotEmptyString(centerBaseConfig.getLeftMenuBgColor()) ? centerBaseConfig.getLeftMenuBgColor() : baseConfig.getLeftMenuBgColor());

        model.addAttribute("name", getUser().getName());
        model.addAttribute("userFlag", getUserFlag());
        model.addAttribute("logoutUrl", "/logout?centerId=" + getUserCentreId());
        model.addAttribute("centreName", getCentreName());
        return "index_v1";
    }

    /**
     * 请求登录界面
     *
     * @return
     */
    @GetMapping({"/login", "/", ""})
    public String login(Model model, Long centreId) {
        String centreName = StringConstans.STR_EMPTY;
        BaseConfig baseConfig = configService.getBaseConfig();
        if (null != centreId) {
            BaseConfig centerBaseConfig = configService.getBaseConfig(centreId);
            if (null != centerBaseConfig && ValidateUtil.isNotEmptyString(centerBaseConfig.getLoginBgImg())) {
                baseConfig = centerBaseConfig;
            }
            Centre centre = centreService.getByKey(centreId);
            if (null != centre) {
                centreName = centre.getName();
            }
        }
        model.addAttribute("centreName", centreName);
        model.addAttribute("loginBgImg", baseConfig.getLoginBgImg());
        return "login1";
    }

    /**
     * 登录验证,记录登录IP历史
     *
     * @param username
     * @param password
     * @param verifyCode
     * @param request
     * @return
     */
    @Log(module = "后台登录", operation = "管理员登录", type = 1)
    @PostMapping("/login")
    @ResponseBody
    public ResultVo ajaxLogin(String username, String password, String verifyCode, HttpServletRequest request) {
        if (StringUtils.isEmpty(verifyCode)) {
            throw new BDException(BusinessCode.VERIFYCODE_NULL);
        }
        Object vc = request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
        if (vc == null) {
            throw new BDException(BusinessCode.VERIFYCODE_NULL);
        }
        if (!StringUtils.equals((CharSequence) vc, verifyCode)) {
            throw new BDException(BusinessCode.VERIFYCODE_ERROR);
        }

        String desPassword = Base64Utils.desEncrypt(password);
        password = MD5Utils.encrypt(username, desPassword);
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
            SysUser sysUser = userService.getUserById(getUserId());
            if (sysUser.getCentreId() != null) {
                if (!centreService.checkExpriedDate(sysUser.getCentreId())) {
                    throw new BDException("商户已到期，请续费！");
                }
            }

            userService.updateLoginIp(getUserId(), IPUtils.getIpAddr(request));
            return ResultVo.ok();
        } catch (AuthenticationException e) {
            logger.info("login error:{}", e.getMessage());
            return ResultVo.error(BusinessCode.ACCOUNT_OR_PSW_ERROR);
        } catch (BDException e) {
            logger.info("login error:{}", e.getMessage());
            return ResultVo.error("商户已到期，请续费！");
        }
    }

    @GetMapping("/logout")
    public String logout(Long centerId) {
        ShiroUtils.logout();
        return "redirect:/login?centerId=" + centerId;
    }

    @GetMapping("/main")
    public String main(Model model) {
        model.addAttribute("defaultDate", DateUtils.getAddDayDate(new Date(), -1));
        Long centerId = getUserCentreId();
        BaseConfig baseConfig = null;
        if (null != centerId) {
            baseConfig = configService.getBaseConfig(centerId);
        }
        if (null == baseConfig || ValidateUtil.isEmptyString(baseConfig.getIndexBgImg())) {
            baseConfig = configService.getBaseConfig();
        }

        model.addAttribute("defaultDate", DateUtils.getAddDayDate(new Date(), -1));
        model.addAttribute("indexBgImg", baseConfig.getIndexBgImg());
        return "main";
    }

    @GetMapping("/403")
    public String error403() {
        return "403";
    }

    /**
     * 随机rgb颜色值
     *
     * @param fc
     * @param bc
     * @return
     */
    private static Color getRandColor(int fc, int bc) {
        Random rnd = new Random();
        if (fc > 255) {
            fc = 255;
        }
        if (bc > 255) {
            bc = 255;
        }
        int r = fc + rnd.nextInt(bc - fc);
        int g = fc + rnd.nextInt(bc - fc);
        int b = fc + rnd.nextInt(bc - fc);
        return new Color(r, g, b);
    }

    /**
     * 得到颜色值
     *
     * @return
     */
    private static int getRandomIntColor() {
        int[] rgb = getRandomRgb();
        int color = 0;
        for (int c : rgb) {
            color = color << 8;
            color = color | c;
        }
        return color;
    }

    /**
     * 得到随机rgb
     *
     * @return
     */
    private static int[] getRandomRgb() {
        Random rnd = new Random();
        int[] rgb = new int[3];
        for (int i = 0; i < 3; i++) {
            rgb[i] = rnd.nextInt(255);
        }
        return rgb;
    }

    @GetMapping("/getKaptchaImage")
    public void getKaptchaImage(HttpServletResponse response, HttpServletRequest request) throws Exception {
        response.setDateHeader("Expires", 0);
        // Set standard HTTP/1.1 no-cache headers.
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        // Set IE extended HTTP/1.1 no-cache headers (use addHeader).
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        // Set standard HTTP/1.0 no-cache header.
        response.setHeader("Pragma", "no-cache");
        // return a jpeg
        response.setContentType("image/jpeg");
        // create the text for the image
        String capText = captchaProducer.createText();
        // store the text in the session
        request.getSession().setAttribute(Constants.KAPTCHA_SESSION_KEY, capText);
        logger.info("capText:{}", capText);
        // create the image with the text
        BufferedImage bi = captchaProducer.createImage(capText);
        // 得到画笔对象
        Graphics2D g2 = bi.createGraphics();
        g2.setColor(Color.GRAY);// 设置边框色
        g2.fillRect(0, 0, bi.getWidth(), bi.getHeight());
//        Color c = getRandColor(200, 250);
        Color c = getRandColor(251, 255);
        g2.setColor(c);// 设置背景色
        //g2.fillRect(0, 2, bi.getWidth(), bi.getHeight() - 4);
        g2.fillRect(0, 0, bi.getWidth(), bi.getHeight() + 10);
        // 绘制干扰线
        Random random = new Random();
        g2.setColor(getRandColor(160, 200));// 设置线条的颜色
//        for (int i = 0; i < 20; i++) {
//            int x = random.nextInt(bi.getWidth() - 1);
//            int y = random.nextInt(bi.getHeight() - 1);
//            int xl = random.nextInt(6) + 1;
//            int yl = random.nextInt(12) + 1;
//            g2.drawLine(x, y, x + xl + 40, y + yl + 20);
//        }

        // 添加噪点
//        float yawpRate = 0.05f;// 噪声率
//        int area = (int) (yawpRate * bi.getWidth() * bi.getHeight());
//        for (int i = 0; i < area; i++) {
//            int x = random.nextInt(bi.getWidth());
//            int y = random.nextInt(bi.getHeight());
//            int rgb = getRandomIntColor();
//            bi.setRGB(x, y, rgb);
//        }
        char[] chars = capText.toCharArray();
        Random rand = new Random();
        int fontSize = bi.getHeight() - 4;
        Font font = new Font("Algerian", Font.ITALIC, fontSize);
        g2.setFont(font);
        for (int i = 0; i < chars.length; i++) {
            AffineTransform affine = new AffineTransform();
            affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1),
                    (bi.getWidth() / chars.length) * i + fontSize / 2, bi.getHeight() / 2);
            g2.setTransform(affine);
            g2.drawChars(chars, i, 1, ((bi.getWidth() - 10) / chars.length) * i + 5,
                    bi.getHeight() / 2 + fontSize / 2 - 10);
        }
        // 添加文字
        //g2.drawString(capText, 100, 100);
        g2.drawString(capText, 100, 108);

        // 释放对象
        g2.dispose();
        ServletOutputStream out = response.getOutputStream();
        // write the data out
        ImageIO.write(bi, "jpg", out);
        try {
            out.flush();
        } finally {
            out.close();
        }
    }
}
